from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from django.utils import timezone
from django.db.models import Q, Count
from django.db import transaction
from django.http import HttpResponse
from typing import Dict, Any

from .models import (
    ReportTemplate, Report, ReportSchedule, ReportData, ReportSubscription
)
from .serializers import (
    ReportTemplateSerializer, ReportSerializer, ReportScheduleSerializer,
    ReportDataSerializer, ReportSubscriptionSerializer,
    ReportGenerateSerializer, ReportStatsSerializer
)
from .services import ReportGenerationService, ReportExportService, ReportScheduleService


class ReportTemplateViewSet(viewsets.ModelViewSet):
    """
    报表模板视图集
    """
    queryset = ReportTemplate.objects.all()
    serializer_class = ReportTemplateSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        queryset = super().get_queryset()
        
        # 过滤参数
        report_type = self.request.query_params.get('type')
        category = self.request.query_params.get('category')
        is_active = self.request.query_params.get('is_active')
        
        if report_type:
            queryset = queryset.filter(report_type=report_type)
        if category:
            queryset = queryset.filter(category=category)
        if is_active is not None:
            queryset = queryset.filter(is_active=is_active.lower() == 'true')
            
        return queryset.order_by('-created_at')
    
    def perform_create(self, serializer):
        serializer.save(created_by=self.request.user)
    
    @action(detail=True, methods=['post'])
    def preview(self, request, pk=None):
        """
        预览报表模板
        """
        template = self.get_object()
        parameters = request.data.get('parameters', {})
        
        try:
            service = ReportGenerationService()
            preview_data = service.preview_template(template, parameters)
            return Response(preview_data)
        except Exception as e:
            return Response(
                {'error': str(e)},
                status=status.HTTP_400_BAD_REQUEST
            )
    
    @action(detail=True, methods=['post'])
    def generate(self, request, pk=None):
        """
        生成报表
        """
        template = self.get_object()
        serializer = ReportGenerateSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        
        try:
            service = ReportGenerationService()
            report = service.generate_report(
                template=template,
                parameters=serializer.validated_data.get('parameters', {}),
                generated_by=request.user,
                title=serializer.validated_data.get('title'),
                description=serializer.validated_data.get('description')
            )
            
            report_serializer = ReportSerializer(report)
            return Response(report_serializer.data)
            
        except Exception as e:
            return Response(
                {'error': str(e)},
                status=status.HTTP_400_BAD_REQUEST
            )
    
    @action(detail=True, methods=['get'])
    def usage_stats(self, request, pk=None):
        """
        模板使用统计
        """
        template = self.get_object()
        
        stats = {
            'total_reports': template.reports.count(),
            'recent_reports': template.reports.filter(
                created_at__gte=timezone.now() - timezone.timedelta(days=30)
            ).count(),
            'active_schedules': template.schedules.filter(is_active=True).count(),
            'subscribers': template.subscriptions.filter(is_active=True).count()
        }
        
        return Response(stats)


class ReportViewSet(viewsets.ModelViewSet):
    """
    报表视图集
    """
    queryset = Report.objects.all()
    serializer_class = ReportSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        queryset = super().get_queryset()
        user = self.request.user
        
        # 只显示用户有权限查看的报表
        queryset = queryset.filter(
            Q(generated_by=user) | Q(is_public=True) | Q(shared_with=user)
        ).distinct()
        
        # 过滤参数
        template_id = self.request.query_params.get('template')
        status_filter = self.request.query_params.get('status')
        start_date = self.request.query_params.get('start_date')
        end_date = self.request.query_params.get('end_date')
        
        if template_id:
            queryset = queryset.filter(template_id=template_id)
        if status_filter:
            queryset = queryset.filter(status=status_filter)
        if start_date:
            queryset = queryset.filter(created_at__gte=start_date)
        if end_date:
            queryset = queryset.filter(created_at__lte=end_date)
            
        return queryset.order_by('-created_at')
    
    @action(detail=True, methods=['get'])
    def download(self, request, pk=None):
        """
        下载报表
        """
        report = self.get_object()
        export_format = request.query_params.get('format', 'pdf')
        
        try:
            service = ReportExportService()
            file_content, content_type, filename = service.export_report(
                report, export_format
            )
            
            response = HttpResponse(file_content, content_type=content_type)
            response['Content-Disposition'] = f'attachment; filename="{filename}"'
            return response
            
        except Exception as e:
            return Response(
                {'error': str(e)},
                status=status.HTTP_400_BAD_REQUEST
            )
    
    @action(detail=True, methods=['post'])
    def share(self, request, pk=None):
        """
        分享报表
        """
        report = self.get_object()
        user_ids = request.data.get('user_ids', [])
        
        try:
            with transaction.atomic():
                for user_id in user_ids:
                    report.shared_with.add(user_id)
                
                return Response({'status': 'shared successfully'})
                
        except Exception as e:
            return Response(
                {'error': str(e)},
                status=status.HTTP_400_BAD_REQUEST
            )
    
    @action(detail=True, methods=['post'])
    def regenerate(self, request, pk=None):
        """
        重新生成报表
        """
        report = self.get_object()
        
        try:
            service = ReportGenerationService()
            new_report = service.regenerate_report(report, request.user)
            
            serializer = self.get_serializer(new_report)
            return Response(serializer.data)
            
        except Exception as e:
            return Response(
                {'error': str(e)},
                status=status.HTTP_400_BAD_REQUEST
            )
    
    @action(detail=False, methods=['get'])
    def stats(self, request):
        """
        报表统计
        """
        user = request.user
        queryset = self.get_queryset()
        
        stats = {
            'total': queryset.count(),
            'completed': queryset.filter(status='completed').count(),
            'failed': queryset.filter(status='failed').count(),
            'processing': queryset.filter(status='processing').count(),
            'by_template': dict(
                queryset.values('template__name')
                .annotate(count=Count('id'))
                .values_list('template__name', 'count')
            ),
            'recent_activity': queryset.filter(
                created_at__gte=timezone.now() - timezone.timedelta(days=7)
            ).count()
        }
        
        serializer = ReportStatsSerializer(stats)
        return Response(serializer.data)


class ReportScheduleViewSet(viewsets.ModelViewSet):
    """
    报表计划视图集
    """
    queryset = ReportSchedule.objects.all()
    serializer_class = ReportScheduleSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        queryset = super().get_queryset()
        user = self.request.user
        
        # 只显示用户创建的计划
        queryset = queryset.filter(created_by=user)
        
        # 过滤参数
        is_active = self.request.query_params.get('is_active')
        template_id = self.request.query_params.get('template')
        
        if is_active is not None:
            queryset = queryset.filter(is_active=is_active.lower() == 'true')
        if template_id:
            queryset = queryset.filter(template_id=template_id)
            
        return queryset.order_by('-created_at')
    
    def perform_create(self, serializer):
        serializer.save(created_by=self.request.user)
    
    @action(detail=True, methods=['post'])
    def activate(self, request, pk=None):
        """
        激活计划
        """
        schedule = self.get_object()
        schedule.is_active = True
        schedule.save()
        
        # 注册到调度系统
        service = ReportScheduleService()
        service.register_schedule(schedule)
        
        return Response({'status': 'activated'})
    
    @action(detail=True, methods=['post'])
    def deactivate(self, request, pk=None):
        """
        停用计划
        """
        schedule = self.get_object()
        schedule.is_active = False
        schedule.save()
        
        # 从调度系统移除
        service = ReportScheduleService()
        service.unregister_schedule(schedule)
        
        return Response({'status': 'deactivated'})
    
    @action(detail=True, methods=['post'])
    def run_now(self, request, pk=None):
        """
        立即执行
        """
        schedule = self.get_object()
        
        try:
            service = ReportScheduleService()
            report = service.execute_schedule(schedule)
            
            serializer = ReportSerializer(report)
            return Response(serializer.data)
            
        except Exception as e:
            return Response(
                {'error': str(e)},
                status=status.HTTP_400_BAD_REQUEST
            )


class ReportDataViewSet(viewsets.ReadOnlyModelViewSet):
    """
    报表数据视图集（只读）
    """
    queryset = ReportData.objects.all()
    serializer_class = ReportDataSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        queryset = super().get_queryset()
        
        # 过滤参数
        report_id = self.request.query_params.get('report')
        data_type = self.request.query_params.get('type')
        
        if report_id:
            queryset = queryset.filter(report_id=report_id)
        if data_type:
            queryset = queryset.filter(data_type=data_type)
            
        return queryset.order_by('section_order', 'created_at')


class ReportSubscriptionViewSet(viewsets.ModelViewSet):
    """
    报表订阅视图集
    """
    queryset = ReportSubscription.objects.all()
    serializer_class = ReportSubscriptionSerializer
    permission_classes = [IsAuthenticated]
    
    def get_queryset(self):
        queryset = super().get_queryset()
        user = self.request.user
        
        # 只显示用户的订阅
        queryset = queryset.filter(user=user)
        
        # 过滤参数
        is_active = self.request.query_params.get('is_active')
        template_id = self.request.query_params.get('template')
        
        if is_active is not None:
            queryset = queryset.filter(is_active=is_active.lower() == 'true')
        if template_id:
            queryset = queryset.filter(template_id=template_id)
            
        return queryset.order_by('-created_at')
    
    def perform_create(self, serializer):
        serializer.save(user=self.request.user)
    
    @action(detail=False, methods=['get'])
    def my_subscriptions(self, request):
        """
        我的订阅
        """
        user = request.user
        subscriptions = ReportSubscription.objects.filter(
            user=user,
            is_active=True
        )
        
        serializer = self.get_serializer(subscriptions, many=True)
        return Response(serializer.data)
    
    @action(detail=True, methods=['post'])
    def unsubscribe(self, request, pk=None):
        """
        取消订阅
        """
        subscription = self.get_object()
        subscription.is_active = False
        subscription.save()
        
        return Response({'status': 'unsubscribed'})